package com.ruoyi.business.service.impl;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.business.mapper.WsdPaymentRecordsMapper;
import com.ruoyi.business.service.IWsdCanteenBalanceService;
import com.ruoyi.business.service.IWsdPaymentRecordsService;
import com.ruoyi.business.service.IWsdRechargeRefundService;
import com.ruoyi.common.core.domain.dto.WsdPaymentRecordsDTO;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.entity.WsdCanteenBalance;
import com.ruoyi.common.core.domain.entity.WsdPaymentRecords;
import com.ruoyi.common.core.domain.table.OrderFoodTable;
import com.ruoyi.common.core.domain.table.OrderFoodVOTable;
import com.ruoyi.common.core.domain.vo.ChartDataVO;
import com.ruoyi.common.core.domain.vo.RechargeRefundVO;
import com.ruoyi.common.core.domain.vo.WsdCanteensOrderVO;
import com.ruoyi.common.core.domain.vo.WsdPaymentRecordsVO;
import com.ruoyi.common.utils.date.DateTimeUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

import static com.ruoyi.common.utils.SecurityUtils.getLoginUser;

/**
 * <p>
 * 充值缴费记录表 服务实现类
 * </p>
 *
 * @author wwq
 * @since 2024-05-18
 */
@Service
public class WsdPaymentRecordsServiceImpl extends ServiceImpl<WsdPaymentRecordsMapper, WsdPaymentRecords> implements IWsdPaymentRecordsService {

    @Autowired
    private WsdPaymentRecordsMapper wsdPaymentRecordsMapper;

    @Autowired
    private IWsdRechargeRefundService wsdRechargeRefundService;

    @Autowired
    private IWsdCanteenBalanceService wsdCanteenBalanceService;


    /**
     * 查询充值缴费记录列表
     *
     * @param
     * @return 充值缴费记录
     */
    @Override
    public List<WsdPaymentRecordsVO> selectWsdPaymentRecordsList(WsdPaymentRecordsDTO wsdPaymentRecordsDTO) {
        SysUser user = getLoginUser().getUser();
        if (!user.isAdmin()) {
            //不是admin
            if (wsdPaymentRecordsDTO.getSchoolsId() == null) {
                wsdPaymentRecordsDTO.setSchoolsId( user.getSchoolId() );
            }
        }
        wsdPaymentRecordsDTO.setIsPaid(true); // 设置为充值成功的记录
        List<WsdPaymentRecordsVO> wsdPaymentRecordsVOS = new ArrayList<>();

        // 日期时间格式化器
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        if (wsdPaymentRecordsDTO.getType() != null) {
            switch (wsdPaymentRecordsDTO.getType()) {
                case 0: // 今天
                    setStartAndEndTime(wsdPaymentRecordsDTO,
                            LocalDateTime.of(LocalDate.now(), LocalTime.MIN),
                            LocalDateTime.of(LocalDate.now(), LocalTime.MAX),
                            dateTimeFormatter);
                    break;
                case 1: // 本周
                    setStartAndEndTime(wsdPaymentRecordsDTO,
                            LocalDateTime.of(LocalDate.now().with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)), LocalTime.MIN),
                            LocalDateTime.of(LocalDate.now().with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)), LocalTime.MAX),
                            dateTimeFormatter);
                    break;
                case 2: // 本月
                    setStartAndEndTime(wsdPaymentRecordsDTO,
                            LocalDateTime.of(LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()), LocalTime.MIN),
                            LocalDateTime.of(LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()), LocalTime.MAX),
                            dateTimeFormatter);
                    break;
                case 3: // 自定义时间
                    // 已经是字符串类型，直接使用
                    break;
                default:
                    throw new IllegalArgumentException("无效的日期类型");
            }
            wsdPaymentRecordsVOS = queryAndProcessPaymentRecords(wsdPaymentRecordsDTO, wsdPaymentRecordsDTO.getSchoolsId(), dateFormatter);
        }

        return wsdPaymentRecordsVOS;
    }

    /**
     * 设置查询时间范围
     * @param dto 查询条件DTO
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param formatter 日期时间格式化器
     */
    private void setStartAndEndTime(WsdPaymentRecordsDTO dto, LocalDateTime startTime, LocalDateTime endTime, DateTimeFormatter formatter) {
        dto.setRechargeTimeStart(startTime.format(formatter));
        dto.setRechargeTimeEnd(endTime.format(formatter));
    }
    /**
     * 查询学期配置充值金额
     * @param dto 查询条件DTO
     * @param schoolId 学校ID
     * @param dateFormatter 日期格式化器
     * @return 处理后的支付记录列表
     */
    private List<WsdPaymentRecordsVO> queryAndProcessPaymentRecords(WsdPaymentRecordsDTO dto, Long schoolId, DateTimeFormatter dateFormatter) {
        List<WsdPaymentRecordsVO> result = new ArrayList<>();
        List<WsdPaymentRecordsVO> records = wsdPaymentRecordsMapper.selectWsdPaymentRecordsList(dto);

        for (WsdPaymentRecordsVO record : records) {
            LocalDateTime rechargeTime = record.getRechargeTime();
            String formattedDate = rechargeTime.format(dateFormatter);
            if (schoolId==null){
                schoolId = record.getSchoolId();
            }
            RechargeRefundVO rechargeRefundVO = wsdRechargeRefundService.existsActiveSemester(schoolId, formattedDate);
            if (rechargeRefundVO != null){
                record.setTotalBreakfastFee(rechargeRefundVO.getTotalBreakfastFee());
                record.setTotalLunchFee(rechargeRefundVO.getTotalLunchFee());
                record.setTotalDinnerFee(rechargeRefundVO.getTotalDinnerFee());
            }
            //查询充值金额
            String studentId = record.getStudent_id();
            WsdCanteenBalance wsdCanteenBalance = new WsdCanteenBalance();
            wsdCanteenBalance.setStudentId(studentId);
            List<WsdCanteenBalance> wsdCanteenBalances = wsdCanteenBalanceService.selectWsdCanteenBalanceList(wsdCanteenBalance);
            //把里面的 balanceBreakfast,balanceLunch,balanceDinner拿出来
            if (wsdCanteenBalances.size() > 0) {
                WsdCanteenBalance wsdCanteenBalance1 = wsdCanteenBalances.get(0);
                record.setTotalRechargeAmountBreakfast(wsdCanteenBalance1.getTotalRechargeAmountBreakfast());
                record.setTotalRechargeAmountLunch(wsdCanteenBalance1.getTotalRechargeAmountLunch());
                record.setTotalRechargeAmountDinner(wsdCanteenBalance1.getTotalRechargeAmountDinner());
            }
            result.add(record);
        }
        return result;
    }

    /**
     * 时间区间统计
     * @return
     */
    @Override
    public ChartDataVO getTotalFeeByDateRange(String startDate, String endDate) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate start = LocalDate.parse(startDate, formatter);
        LocalDate end = LocalDate.parse(endDate, formatter);

        List<Map<String, Object>> dateRangeData = wsdPaymentRecordsMapper.getTotalFeeByDateRange(startDate, endDate);

        // 创建一个包含查询区间内的所有日期的列表
        List<String> labels = new ArrayList<>();
        List<Integer> values = new ArrayList<>();
        int totalAmount = 0;

        while (!start.isAfter(end)) {
            labels.add(start.toString());
            values.add(0);
            start = start.plusDays(1);
        }

        // 更新列表中的数据
        for (Map<String, Object> record : dateRangeData) {
            String date = record.get("date").toString();
            BigDecimal totalFee = (BigDecimal) record.get("totalFee");
            totalAmount += totalFee.intValue();
            int index = labels.indexOf(date);
            if (index != -1) {
                values.set(index, totalFee.intValue());
            }
        }

        // 结果返回格式
        ChartDataVO result = new ChartDataVO();
        result.setLabels(labels);
        result.setValues(values);
        result.setTotalAmount(totalAmount);

        return result;
    }

    /**
     * 月统计
     * @return
     */
    @Override
    public ChartDataVO getTotalFeeByYear() {
        List<Map<String, Object>> monthlyData = wsdPaymentRecordsMapper.getTotalFeeByMonth();

        // 创建一个包含12个月的月份列表
        List<String> labels = new ArrayList<>();
        List<Integer> values = new ArrayList<>();
        int totalAmount = 0;

        for (int i = 1; i <= 12; i++) {
            labels.add(i + "月");
            values.add(0);
        }

        // 更新列表中的数据
        for (Map<String, Object> record : monthlyData) {
            Integer month = (Integer) record.get("month");
            BigDecimal totalFee = (BigDecimal) record.get("totalFee");
            totalAmount += totalFee.intValue();
            values.set(month - 1, totalFee.intValue());
        }

        // 结果返回格式
        ChartDataVO result = new ChartDataVO();
        result.setLabels(labels);
        result.setValues(values);
        result.setTotalAmount(totalAmount);

        return result;
    }

    /**
     * 年统计
     * @return
     */
    @Override
    public ChartDataVO getTotalFeeByMonth() {
        List<Map<String, Object>> yearlyData = wsdPaymentRecordsMapper.getTotalFeeByYear();

        // 获取当前年份
        int currentYear = Calendar.getInstance().get(Calendar.YEAR);

        // 创建一个包含过去五年的年份列表
        List<String> labels = new ArrayList<>();
        List<Integer> values = new ArrayList<>();
        int totalAmount = 0;

        for (int i = 0; i < 5; i++) {
            labels.add(String.valueOf(currentYear - i));
            values.add(0);
        }

        // 更新列表中的数据
        for (Map<String, Object> record : yearlyData) {
            String year = String.valueOf(record.get("year"));
            BigDecimal totalFee = (BigDecimal) record.get("totalFee");
            totalAmount += totalFee.intValue();
            int index = labels.indexOf(year);
            if (index != -1) {
                values.set(index, totalFee.intValue());
            }
        }

        // 结果返回格式
        ChartDataVO result = new ChartDataVO();
        result.setLabels(labels);
        result.setValues(values);
        result.setTotalAmount(totalAmount);

        return result;
    }

    @Override
    public List<WsdPaymentRecords> selectList(WsdPaymentRecords wsdPaymentRecords) {

        List<WsdPaymentRecords> wsdPaymentRecordsList = wsdPaymentRecordsMapper.selectList(wsdPaymentRecords);

        return wsdPaymentRecordsList;
    }

    @Override
    public List<WsdPaymentRecords> wsdPaymentRecords(WsdPaymentRecords wsdPaymentRecords) {
        return wsdPaymentRecordsMapper.selectWsdPaymentRecords(wsdPaymentRecords);
    }

    @Override
    public WsdPaymentRecords byTransactionId(String transactionId) {
        return wsdPaymentRecordsMapper.byTransactionId(transactionId);
    }
    @Override
    public List<OrderFoodVOTable>  selectWsdPaymentRecordsByPaymentId(Long paymentId){
        WsdPaymentRecords wsdPaymentRecords = wsdPaymentRecordsMapper.selectWsdPaymentRecordsByPaymentId(paymentId);
        WsdCanteensOrderVO wsdCanteensOrderVO = new WsdCanteensOrderVO();
        BeanUtils.copyProperties(wsdPaymentRecords,wsdCanteensOrderVO);
        String currentDateString = DateTimeUtil.getCurrentDateString();
        //缴费配置
        RechargeRefundVO rechargeRefundVO = wsdRechargeRefundService.existsActiveSemester(wsdPaymentRecords.getSchoolsId(),currentDateString);
        Integer meals = 0;
        if (!BigDecimal.ZERO.equals( wsdCanteensOrderVO.getTotalFee() )) {
            if (wsdCanteensOrderVO.getMealType() == 0) {
                if (rechargeRefundVO.getBreakfastFee().compareTo(BigDecimal.ZERO) != 0) {
                    BigDecimal result = wsdCanteensOrderVO.getTotalFee().divide( rechargeRefundVO.getBreakfastFee(), 0, RoundingMode.HALF_UP );
                    meals = result.intValue();
                }
            } else if (wsdCanteensOrderVO.getMealType()==1) {
                if (rechargeRefundVO.getLunchFee().compareTo(BigDecimal.ZERO) != 0) {
                    BigDecimal result = wsdCanteensOrderVO.getTotalFee().divide( rechargeRefundVO.getLunchFee(), 0, RoundingMode.HALF_UP );
                    meals = result.intValue();
                }
            }else if (wsdCanteensOrderVO.getMealType()==2) {
                if (rechargeRefundVO.getDinnerFee().compareTo(BigDecimal.ZERO) != 0) {
                    BigDecimal result = wsdCanteensOrderVO.getTotalFee().divide( rechargeRefundVO.getDinnerFee(), 0, RoundingMode.HALF_UP );
                    meals = result.intValue();
                }
            } else if (wsdCanteensOrderVO.getMealType()==3) {
                BigDecimal resultA = BigDecimal.ZERO;
                BigDecimal resultB = BigDecimal.ZERO;
                BigDecimal resultC = BigDecimal.ZERO;
                if (rechargeRefundVO.getDinnerFee().compareTo(BigDecimal.ZERO) != 0) {
                    resultA = rechargeRefundVO.getTotalDinnerFee().divide( rechargeRefundVO.getDinnerFee(), 0, RoundingMode.HALF_UP );
                }
                if (rechargeRefundVO.getLunchFee().compareTo(BigDecimal.ZERO) != 0) {
                    resultB = rechargeRefundVO.getTotalLunchFee().divide( rechargeRefundVO.getLunchFee(), 0, RoundingMode.HALF_UP );
                }
                if (rechargeRefundVO.getBreakfastFee().compareTo(BigDecimal.ZERO) != 0) {
                    resultC = rechargeRefundVO.getTotalBreakfastFee().divide( rechargeRefundVO.getBreakfastFee(), 0, RoundingMode.HALF_UP );
                }
                meals = resultA.add( resultB ).add( resultC ).intValue();
            }
        }
        wsdCanteensOrderVO.setMeals( meals );
        //订餐数
        String mealsNum = String.valueOf( meals );
        // 创建一个 DateTimeFormatter 对象，定义日期和时间的格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        DateTimeFormatter localDate = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        //订餐日期
        String orderDate = rechargeRefundVO.getStartDate().format(localDate)+" "+"~"+" "+ rechargeRefundVO.getEndDate().format( localDate );
        List<OrderFoodVOTable> orderFoodVOTableList = new ArrayList<>();
        //学生信息
        OrderFoodVOTable orderFoodVOTable = new OrderFoodVOTable();
        orderFoodVOTable.setTitle( "学生信息" );
        List<OrderFoodTable> orderFoodTableList = new ArrayList<>();
        orderFoodTableList.add(new OrderFoodTable("学生姓名", wsdCanteensOrderVO.getStudentName()));
        orderFoodTableList.add(new OrderFoodTable("学校名称", wsdCanteensOrderVO.getSchoolName()));
        orderFoodTableList.add(new OrderFoodTable("年级", wsdCanteensOrderVO.getGradeName()));
        orderFoodTableList.add(new OrderFoodTable("班级", wsdCanteensOrderVO.getClassName()));
        orderFoodTableList.add(new OrderFoodTable("家长手机号", wsdCanteensOrderVO.getParentMobile()));
        orderFoodVOTable.setList(orderFoodTableList);
        orderFoodVOTableList.add(orderFoodVOTable);

        //早餐订餐详情
        if (wsdCanteensOrderVO.getMealType() == 0 || wsdCanteensOrderVO.getMealType()==3 && rechargeRefundVO.getTotalBreakfastFee().compareTo(BigDecimal.ZERO) != 0) {
            orderFoodVOTable = new OrderFoodVOTable();
            orderFoodVOTable.setTitle( "早餐订餐详情" );
            orderFoodTableList = new ArrayList<>();
            orderFoodTableList.add( new OrderFoodTable( "订餐日期", orderDate ) );
            if (wsdCanteensOrderVO.getMealType()==3) {
                //订餐数
                BigDecimal result = rechargeRefundVO.getTotalBreakfastFee().divide( rechargeRefundVO.getBreakfastFee(), 0, RoundingMode.HALF_UP );
                orderFoodTableList.add( new OrderFoodTable( "订餐数", result.toString() ) );
                orderFoodTableList.add( new OrderFoodTable( "合计金额", rechargeRefundVO.getTotalBreakfastFee().toString() ) );
            }else {
                orderFoodTableList.add( new OrderFoodTable( "订餐数", mealsNum ) );
                orderFoodTableList.add( new OrderFoodTable( "合计金额", wsdCanteensOrderVO.getTotalFee().toString() ) );
            }
            orderFoodVOTable.setList( orderFoodTableList );
            orderFoodVOTableList.add( orderFoodVOTable );
        }if (wsdCanteensOrderVO.getMealType()==1 || wsdCanteensOrderVO.getMealType()==3 && rechargeRefundVO.getTotalLunchFee().compareTo(BigDecimal.ZERO) != 0) {
            //午餐订餐详情
            orderFoodVOTable = new OrderFoodVOTable();
            orderFoodVOTable.setTitle( "午餐订餐详情" );
            orderFoodTableList = new ArrayList<>();
            orderFoodTableList.add( new OrderFoodTable( "订餐日期", orderDate ) );
            if (wsdCanteensOrderVO.getMealType()==3) {
                //订餐数
                BigDecimal result = rechargeRefundVO.getTotalLunchFee().divide( rechargeRefundVO.getLunchFee(), 0, RoundingMode.HALF_UP );
                orderFoodTableList.add( new OrderFoodTable( "订餐数", result.toString() ) );
                orderFoodTableList.add( new OrderFoodTable( "合计金额", rechargeRefundVO.getTotalLunchFee().toString() ) );
            }else {
                orderFoodTableList.add( new OrderFoodTable( "订餐数", mealsNum ) );
                orderFoodTableList.add( new OrderFoodTable( "合计金额", wsdCanteensOrderVO.getTotalFee().toString() ) );
            }
            orderFoodVOTable.setList( orderFoodTableList );
            orderFoodVOTableList.add( orderFoodVOTable );
        }if (wsdCanteensOrderVO.getMealType()==2 || wsdCanteensOrderVO.getMealType()==3 && rechargeRefundVO.getTotalDinnerFee().compareTo(BigDecimal.ZERO) != 0) {
            //晚餐订餐详情
            orderFoodVOTable = new OrderFoodVOTable();
            orderFoodVOTable.setTitle( "晚餐订餐详情" );
            orderFoodTableList = new ArrayList<>();
            orderFoodTableList.add( new OrderFoodTable( "订餐日期", orderDate) );
            if (wsdCanteensOrderVO.getMealType()==3) {
                //订餐数
                BigDecimal result = rechargeRefundVO.getTotalDinnerFee().divide( rechargeRefundVO.getDinnerFee(), 0, RoundingMode.HALF_UP );
                orderFoodTableList.add( new OrderFoodTable( "订餐数", result.toString() ) );
                orderFoodTableList.add( new OrderFoodTable( "合计金额", rechargeRefundVO.getTotalDinnerFee().toString() ) );
            }else {
                orderFoodTableList.add( new OrderFoodTable( "订餐数", mealsNum ) );
                orderFoodTableList.add( new OrderFoodTable( "合计金额", wsdCanteensOrderVO.getTotalFee().toString() ) );
            }
            orderFoodVOTable.setList( orderFoodTableList );
            orderFoodVOTableList.add( orderFoodVOTable );
        }
        //缴费详情
        orderFoodVOTable = new OrderFoodVOTable();
        orderFoodVOTable.setTitle( "缴费详情" );
        orderFoodTableList = new ArrayList<>();
        orderFoodTableList.add(new OrderFoodTable("订餐总数", mealsNum));
        orderFoodTableList.add(new OrderFoodTable("合计缴费", wsdCanteensOrderVO.getTotalFee().toString()));
        //缴费方式
        String rechargeType = "";
        switch (wsdCanteensOrderVO.getRechargeType()) {
            case 0:
                rechargeType = "微信支付";
                break;
            case 1:
                rechargeType = "支付宝支付";
                break;
            case 2:
                rechargeType = "现金支付";
                break;
        }
        orderFoodTableList.add(new OrderFoodTable("缴费方式", rechargeType));
        orderFoodTableList.add(new OrderFoodTable("缴费时间", wsdCanteensOrderVO.getFeeTime().format(formatter)));
        orderFoodVOTable.setList(orderFoodTableList);
        orderFoodVOTableList.add(orderFoodVOTable);
        return orderFoodVOTableList;
    }
}
